package com.flute.icrawler.app.processor.store;

import java.io.File;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.Date;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.flute.icrawler.app.entity.CrawlResult;
import com.flute.icrawler.app.processor.AbstractProcessor;
import com.flute.icrawler.app.result.StoreImpFactory;
import com.flute.icrawler.app.service.CrawlService;
import com.flute.icrawler.app.service.MySqlService;
import com.flute.icrawler.app.util.ParameterKey;
import com.flute.icrawler.framework.framework.CrawlUrl;
import com.flute.icrawler.framework.framework.container.AdditionalUrlInformation.Additionals;
import com.flute.icrawler.framework.framework.container.NumberStringValue;
import com.flute.icrawler.framework.processor.result.FilterProcessorResult;
import com.flute.icrawler.framework.processor.result.SuccessProcessorResult;
import com.flute.tools.data.DataRecord;
import com.flute.tools.data.mysql.ConnectionInformation;

/**
 * 本地镜像文件存储
 * 
 * @author jiangbo
 * 
 */
public class LocalMirrorStore extends AbstractProcessor {

	private static final Logger LOGGER = LoggerFactory
			.getLogger(LocalMirrorStore.class);

	public String filterReg = "";

	public String matchReg = "";

	public String fileSavePath = "../mirror/";

	public String defaultCharset = "utf-8";

	public String dbTableName = "test";

	public String dbName = "crawler";

	public String dbIp = "127.0.0.1";

	public String dbUserName = "crawler";

	public String dbPassWord = "crawler";

	public String dbPort = "3306";

	private int index = 0;

	@Override
	public void process(CrawlUrl crawlUrl) {
		// TODO Auto-generated method stub

		LOGGER.debug("LocalMirrorStore:{}", crawlUrl.getUrl());

		if (!CrawlService.match(crawlUrl.getUrl(), filterReg, matchReg)) {
			LOGGER.debug("unmatch url=" + crawlUrl.getUrl() + filterReg + " "
					+ matchReg);
			crawlUrl.registerProcessorResult(new FilterProcessorResult());
			return;
		}

		CrawlResult result = (CrawlResult) crawlUrl.getResultParameter(
				ParameterKey.RESULT_CRAWL).getValue();
		NumberStringValue currentID = (NumberStringValue) crawlUrl
				.getAdditionalUrlInformation().getValue(Additionals.ResourceID);

		result.setId(currentID.getNumber().intValue());

		if (null == result) {
			LOGGER.error(crawlUrl.getUrl() + " result is null!");
			return;
		}
		LOGGER.debug("LocalMirrorStore:{}", "LocalMirrorStore:" + "getCharSet="
				+ result.getCharSet() + "getContentType="
				+ result.getContentType() + "hasContent="
				+ (result.getContent() == null));
		String outPutPath = null;
		LOGGER.info("begin to create path" + result.getUrl());
		while (null == outPutPath) {
			try {
				outPutPath = createFile(result);
				result.setFileSavePath(outPutPath);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				LOGGER.warn("occur an exception create filepath again:{}", e);
				continue;
			}
		}

		LOGGER.info("begin to save" + result.getUrl() + "->"
				+ result.getFileSavePath());

		// 写映射表

		DataRecord dataRecord = new DataRecord();
		dataRecord.AddField(ParameterKey.COLUMN_URL, result.getUrl());
		dataRecord.AddField(ParameterKey.COLUMN_PATH, outPutPath);

		String charset = result.getCharSet();
		if (null == charset || "".equals(charset)) {
			charset = defaultCharset;
			LOGGER.warn("charset is null set charset=" + charset);
		}
		dataRecord.AddField(ParameterKey.COLUMN_CHARSET, charset);

		dataRecord.AddField(ParameterKey.COLUMN_CREATE_TIME, new Timestamp(
				new Date().getTime()).toString());

		// LOGGER.info("dataRecord" + result.getUrl() + "->" + dataRecord);

		// BerkeleyDatabaseService.getInstance().addDataRecord(dataRecord);
		ConnectionInformation connectionInformation = new ConnectionInformation();
		connectionInformation.setDbName(dbName);
		connectionInformation.setHost(dbIp);
		connectionInformation.setUserName(dbUserName);
		connectionInformation.setPassword(dbPassWord);
		connectionInformation.setPort(dbPort);

		// LOGGER.info("begin to add" + result.getUrl());
		MySqlService.getInstance(connectionInformation).addDataRecord(
				dbTableName, dataRecord);
		// LOGGER.info("end to add " + result.getUrl());

		StoreImpFactory.getFileStore().store(result);

		crawlUrl.registerProcessorResult(new SuccessProcessorResult());

		LOGGER.info("save ok " + result.getUrl() + "->"
				+ result.getFileSavePath());

	}

	/**
	 * 创建文件及其包含的文件夹
	 * 
	 * @param strFile
	 *            可以使用的文件名字 包含完整路径
	 * @throws IOException
	 */
	private String createFile(CrawlResult crawlResult) throws IOException {

		StringBuilder stringBuilder = new StringBuilder();
		// 文件保存的路径
		String outPath = "";
		if (crawlResult.getContentType().contains("image")) {

			String fileType = crawlResult.getContentType().substring(
					crawlResult.getContentType().indexOf("/") + 1);

			stringBuilder.append(fileSavePath)
					.append(crawlResult.getHostName()).append("/Imgs").append(
							"/").append(index).append("/").append(
							crawlResult.getId()).append("/").append(
							CrawlService.getLocalIp()).append("_").append(
							System.currentTimeMillis()).append(".").append(
							fileType);

		} else {
			stringBuilder.append(fileSavePath)
					.append(crawlResult.getHostName()).append("/Links").append(
							"/").append(index).append("/").append(
							crawlResult.getId()).append("/").append(
							CrawlService.getLocalIp()).append("_").append(
							System.currentTimeMillis()).append(".").append(
							"html");

		}

		outPath = stringBuilder.toString();
		File file = new File(outPath);

		// 如果文件夹不存在则创建
		File fileDirs = new File(file.getParent());
		if (!fileDirs.exists()) {
			fileDirs.mkdirs();
		}

		// 如果文件存在则需要修改文件名称
		if (!file.exists()) {

			// 如果创建成功返回路径
			if (file.createNewFile()) {
				return outPath;
			}
			// 如果文件创建失败了 说明文件夹满了就切换文件夹
			else {
				index++;
				return null;
			}
		}
		// 如果已经存在切换文件名字并返回
		else {

			return null;
		}

	}

}
